// Ants.cpp : Defines the entry point for the console application.
//

//#include "stdafx.h"

#include <boost/spirit/core.hpp>
#include <iostream>
#include <stack>
#include <functional>
#include <string>
#include <list>
#include <fstream>
#include <map>


using namespace std;
using namespace boost::spirit;


enum EInstruction
{
   EI_Sense = 0  
  ,EI_Mark
  ,EI_Unmark
  ,EI_PickUp
  ,EI_Drop
  ,EI_Turn
  ,EI_Move
  ,EI_Flip
  ,None
};
enum ESensedir
{
    Here
   ,Ahead
   ,LeftAhead
   ,RightAhead
};
enum  ECond
{
   Friend = 0
  ,Foe
  ,FriendWithFood
  ,FoeWithFood
  ,Food
  ,Rock
  ,Marker
  ,FoeMarker
  ,Home
  ,FoeHome
};
enum ELeftRight
{
  ELeft = 0
 ,ERight
};

// TODO improve
struct Instruction
{
  Instruction ( ): m_inst(None) {};
  void InitMark(long i, long state) { m_inst = EI_Mark; m_i = i; m_st1 = state;};
  void InitUnmark(long i, long st) { m_inst = EI_Unmark; m_i = i; m_st1 = st;};
  void InitPickUp(long st1, long st2) { m_inst = EI_PickUp; m_st1 = st1; m_st2 = st2;};
  void InitDrop(long st) { m_inst = EI_Drop; m_st1 = st;};
  void InitTurn(ELeftRight lr, long st) { m_inst = EI_Turn; m_lr = lr; m_st1 = st;};
  void InitMove(long st1, long st2){ m_inst = EI_Move; m_st1 = st1; m_st2 = st2;};
  void InitFlip(long p, long st1, long st2) {m_inst = EI_Flip; m_p = p, m_st1 = st1; m_st2 = st2;};
  void InitSense(ESensedir dir, long st1, long st2, ECond cond) {m_dir = dir, m_inst = EI_Sense; m_cond = cond;  m_st1 = st1; m_st2 = st2;};

  EInstruction m_inst;
  long m_st1;
  long m_st2;
  long m_p;
  long m_i;
  ELeftRight m_lr;
  ESensedir m_dir;
  ECond m_cond;
};

//callbacks
struct PushVal
{
	PushVal(stack<long>& st) : m_st(st) {}
	void operator () (const char* b, const char* e) const
    {
	   string str(b,e);
	   m_st.push(atoi(str.c_str()));
    }
  stack<long>& m_st;
};

struct PushLong
{
	PushLong(stack<long>& st, long val) : m_val(val), m_st(st) {}
	void operator () (const char*, const char*) const
    {
	   m_st.push(m_val);
    }
  stack<long>& m_st;
  long m_val;
};

struct MarkOP
{
  MarkOP(std::list<Instruction>& lst,stack<long>& st, bool isUnmark = false)
	 :m_lst(lst), m_st(st), m_isUnmark(isUnmark) {}
  void operator () (const char*, const char*) const
  { 
	  Instruction instr;
	  long val2 = m_st.top();
	  m_st.pop();
	  long val1 = m_st.top();
	  m_st.pop();
	  if (!m_isUnmark) 
		  instr.InitMark(val1,val2);
	  else instr.InitUnmark(val1,val2);
	  m_lst.push_back (instr);
  }
  std::list<Instruction>& m_lst;
  stack<long>& m_st;
  bool m_isUnmark;
};

struct PickUp
{
  PickUp(std::list<Instruction>& lst, stack<long>& st, bool isDrop = false)
	 :m_lst(lst), m_st(st), m_isDrop(isDrop) {}
  void operator () (const char*, const char*) const
  { 
	  Instruction instr;
	  long val2 = m_st.top();
	  m_st.pop();
	  if ( m_isDrop ) 
		  instr.InitDrop(val2);
	  else 
	  { instr.InitPickUp(m_st.top(),val2); m_st.pop();}
	  m_lst.push_back (instr);
  }
  std::list<Instruction>& m_lst;
  stack<long>& m_st;
  bool m_isDrop;
};

struct Move
{
  Move(std::list<Instruction>& lst, stack<long>& st) :m_lst(lst), m_st(st) {}
  void operator () (const char*, const char*) const
  { 
	  Instruction instr;
	  long val2 = m_st.top(); m_st.pop();
	  long val1 = m_st.top(); m_st.pop();
	  instr.InitMove(val1,val2);
	  m_lst.push_back (instr);
  }
  std::list<Instruction>& m_lst;
  stack<long>& m_st;
};

struct Flip
{
  Flip(std::list<Instruction>& lst, stack<long>& st) :m_lst(lst), m_st(st) {}
  void operator () (const char*, const char*) const
  { 
	  Instruction instr;
	  long val3 = m_st.top();m_st.pop();
	  long val2 = m_st.top();m_st.pop();
	  long val1 = m_st.top();m_st.pop();
	  instr.InitFlip(val1,val2,val3);
	  m_lst.push_back (instr);
  }
  std::list<Instruction>& m_lst;
  stack<long>& m_st;
};

struct Turn
{
  Turn(std::list<Instruction>& lst, stack<long>& st) :m_lst(lst), m_st(st) {}
  void operator () (const char*, const char*) const
  { 
	  Instruction instr;
	  long val2 = m_st.top();m_st.pop();
	  long val1 = m_st.top();m_st.pop();
	  instr.InitTurn((ELeftRight) val1, val2);
	  m_lst.push_back (instr);
  }
  std::list<Instruction>& m_lst;
  stack<long>& m_st;
};

struct Sense
{
  Sense(std::list<Instruction>& lst, stack<long>& st) :m_lst(lst), m_st(st) {}
  void operator () (const char*, const char*) const
  { 
	  Instruction instr;
	  long val4 = m_st.top();m_st.pop();
	  long val3 = m_st.top();m_st.pop();
	  long val2 = m_st.top();m_st.pop();
	  long val1 = m_st.top();m_st.pop();
	  long val(0); 
	  bool isMark = false;
	  if (!m_st.empty()) {isMark  = true; val = m_st.top();m_st.pop();}

	  if (isMark)
	  {
		  instr.InitSense( (ESensedir)  val, val1, val2, (ECond) val3);
	      instr.m_i = val4;
	  }else 
	  {
		  instr.InitSense( (ESensedir)  val1, val2, val3, (ECond) val4);
	  }
	  m_lst.push_back (instr);
  }
  std::list<Instruction>& m_lst;
  stack<long>& m_st;
};

struct AntReader : public grammar<AntReader>
{
	AntReader(std::list<Instruction>& instr_lst)
		: m_lst(instr_lst) {}

    template <typename ScannerT>
    struct definition
    {
        definition(AntReader const& self)
        {
            integer = lexeme_d[(+digit_p)];

			sensedir = str_p("Here") [PushLong((stack<long>&)self.m_eval,(long)Here)]
					 | str_p("Ahead") [PushLong((stack<long>&)self.m_eval,(long)Ahead)]
					 | str_p("LeftAhead") [PushLong((stack<long>&)self.m_eval,(long)LeftAhead)]
					 | str_p("RightAhead") [PushLong((stack<long>&)self.m_eval,(long)RightAhead)];

			cond =  str_p("FriendWithFood") [PushLong((stack<long>&)self.m_eval,(long)FriendWithFood)]
				   |str_p("FoeWithFood") [PushLong((stack<long>&)self.m_eval,(long)FoeWithFood)]
			       |str_p("FoeMarker") [PushLong((stack<long>&)self.m_eval,(long)FoeMarker)]
			       |str_p("FoeHome") [PushLong((stack<long>&)self.m_eval,(long)FoeHome)]
			       |str_p("Friend") [PushLong((stack<long>&)self.m_eval,(long)Friend)]
				   |str_p("Foe") [PushLong((stack<long>&)self.m_eval,(long)Foe)]
				   |str_p("Food") [PushLong((stack<long>&)self.m_eval,(long)Food)]
				   |str_p("Rock") [PushLong((stack<long>&)self.m_eval,(long)Rock)]
				   |str_p("Marker") [PushLong((stack<long>&)self.m_eval,(long)Marker)] >> i[PushVal((stack<long>&)self.m_eval)]
				   |str_p("Home") [PushLong((stack<long>&)self.m_eval,(long)Home)];
				   
			state = integer;
			i = integer;
			leftright = str_p("Left") [PushLong((stack<long>&)self.m_eval,(long)ELeft)] | str_p("Right")[PushLong((stack<long>&)self.m_eval,(long)ERight)]; 
			instruction =  (str_p("Mark")>> i[PushVal((stack<long>&)self.m_eval)] >> state[PushVal((stack<long>&)self.m_eval)]) [MarkOP(self.m_lst, (stack<long>&)self.m_eval)]
						  |(str_p("Unmark")>> i[PushVal((stack<long>&)self.m_eval)] >> state[PushVal((stack<long>&)self.m_eval)]) [MarkOP(self.m_lst, (stack<long>&)self.m_eval,true)]
						  |(str_p("Drop")>> state[PushVal((stack<long>&)self.m_eval)]) [PickUp(self.m_lst, (stack<long>&)self.m_eval,true)]
						  |(str_p("PickUp")>> state[PushVal((stack<long>&)self.m_eval)] >> state[PushVal((stack<long>&)self.m_eval)]) [PickUp(self.m_lst, (stack<long>&)self.m_eval)]
						  |(str_p("Move")>> state[PushVal((stack<long>&)self.m_eval)]) >> state[PushVal((stack<long>&)self.m_eval)] [Move(self.m_lst, (stack<long>&)self.m_eval)]
						  |(str_p("Flip")>> state[PushVal((stack<long>&)self.m_eval)] >> state[PushVal((stack<long>&)self.m_eval)]) >> state[PushVal((stack<long>&)self.m_eval)] [Flip(self.m_lst, (stack<long>&)self.m_eval)]
						  |(str_p("Turn")>> leftright >> state[PushVal((stack<long>&)self.m_eval)]) [Turn(self.m_lst, (stack<long>&)self.m_eval)]
						  |(str_p("Sense")>> sensedir >> state[PushVal((stack<long>&)self.m_eval)]) >> state[PushVal((stack<long>&)self.m_eval)] >> cond [Sense(self.m_lst, (stack<long>&)self.m_eval)];
			
			instructions = *instruction;
		}

        rule<ScannerT> i, integer, state, instruction, leftright, cond,sensedir,instructions;
        rule<ScannerT> const& start() const { return instructions; }
    };

    stack<long> m_eval;
	std::list<Instruction>& m_lst;
};


enum Color
{
	 Red
	,Black
};
class Helper
{
public:
	static int turn (ELeftRight lr, int dir)
	{
		return lr == ELeft ? (dir + 5) % 6 :(dir + 1) % 6;
	}
	static Color other_color(Color c)
	{
		return c == Red ? Black : Red;
	}
};
class Map 
{
public:
struct Cell
{
	Cell( char val = 0)
		:m_val(val)
	{
		memset(m_redmarker,0,sizeof(int)*6);
		memset(m_blackmarker,0,sizeof(int)*6);
	}
	int  m_redmarker[6];
	int  m_blackmarker[6];
  char m_val;
};
struct Position
{
	Position( int x = 0, int y = 0) : m_x(x), m_y(y) {}
	bool operator == (const Position& p)const {return m_x == p.m_x && m_y == p.m_y;}
	int m_x;
	int m_y;
};
enum Land
{
	 Rocky = '#'
	,Clear = '.'
	,RedAntHill = '+'
	,BlackAntHill = '-'
};
typedef vector<vector<Cell>> Matrix;
public:
	Map(const std::string& filename)
	{
		long x(0);
		long y(0);
		ifstream strm;
		strm.open(filename.c_str());
		 strm>>x; 
		 strm>>y;
		 m_map.resize(y);
     for( int i = 0; i < y; i++ )
		 {
			 m_map[i].resize(x);
		 }
		 char ch(0);
		 for (int i = 0; i < y; i++)
			 for(int j = 0; j < x; j++)
			 {
					strm >> m_map[i][j].m_val;
			 }
		strm.close();
	}
	void set_marker_at(const Position& p, Color c, int i)
	{
		if ( c == Red)
		   m_map[p.m_y][p.m_x].m_redmarker[i] = 1;
		else
		   m_map[p.m_y][p.m_x].m_blackmarker[i] = 1;
	}

  void clear_marker_at(const Position& p, Color c, int i) 
	{
		if ( c == Red)
		   m_map[p.m_y][p.m_x].m_redmarker[i] = 0;
		else
		   m_map[p.m_y][p.m_x].m_blackmarker[i] = 0;
	}
  bool check_marker_at(const Position& p, Color c, int i)
	{
		if ( c == Red)
		   return m_map[p.m_y][p.m_x].m_redmarker[i] == 1;
		else
		   return m_map[p.m_y][p.m_x].m_blackmarker[i] == 1;
	}

  bool check_any_marker_at(const Position& p, Color c)
	{
		int* pM = (c == Red ? m_map[p.m_y][p.m_x].m_redmarker : m_map[p.m_y][p.m_x].m_blackmarker);
		for (int i = 0; i < 6; i++)
			if ( pM[i] != 0) return true;
		return false;
	}
	
  bool anthill_at (const Position& pos, Color c)
	{
		if ( c == Red ) 
		  return m_map[pos.m_y][pos.m_x].m_val == RedAntHill;
		else  return m_map[pos.m_y][pos.m_x].m_val == BlackAntHill;
	}
	bool rocky(const Position& pos)
	{
		return m_map[pos.m_y][pos.m_x].m_val == Rocky; 
	}
	int food_at(const Position& p)
	{
		int ret = 0;
		if (isdigit(m_map[p.m_y][p.m_x].m_val))
		{
			ret = m_map[p.m_y][p.m_x].m_val - 48;
		}
		return ret;
	}
  void set_food_at(const Position& p, int food) 
	{
     assert(food >= 0 && food <= 9);
		 m_map[p.m_y][p.m_x].m_val = food + 48;
	}
	static Position adjacent_cell (const Position& pos, int direction)
	{
		assert(direction >= 0 && direction <= 5);
		switch (direction)
		{
		 case 0: return Position(pos.m_x+1,pos.m_y);break;
		 case 1: return pos.m_y % 2 == 0 ? Position(pos.m_x,pos.m_y + 1) : Position(pos.m_x+1,pos.m_y+1);  break;
		 case 2: return pos.m_y % 2 == 0 ? Position(pos.m_x - 1,pos.m_y + 1) : Position(pos.m_x,pos.m_y+1);break;
		 case 3:return Position(pos.m_x-1,pos.m_y); break;
     case 4:return pos.m_y % 2 == 0 ? Position(pos.m_x - 1,pos.m_y - 1) : Position(pos.m_x,pos.m_y-1); break;
		 case 5: return pos.m_y % 2 == 0 ? Position(pos.m_x,pos.m_y - 1) : Position(pos.m_x+1,pos.m_y-1);break;
		 default : assert(0); break;
		};
		return Map::Position(-1,-1);
	}
	static Position sensed_cell(const Position& p, int d, ESensedir sd)
	{
		switch (sd)
		{
		  case Here: return p;break;
		  case Ahead: return adjacent_cell(p, d);break;
			case LeftAhead: return adjacent_cell(p, Helper::turn(ELeft,d));break;
			case RightAhead: return adjacent_cell(p, Helper::turn(ERight,d));break;
			default: assert(0);
		}
    return Map::Position(-1,-1);
	}
	bool isRedHill (int i, int j) const
	{
    return m_map[i][j].m_val == RedAntHill;
	}
  bool isBlackHill (int i, int j) const
	{
    return m_map[i][j].m_val == BlackAntHill;
	}
  char valAt(int i, int j)
	{
     return m_map[i][j].m_val; 
	}
  int szX () const {return (int)m_map[0].size();}

	int szY () const {return (int)m_map.size();}
protected:
	Matrix m_map;
};


struct Ant
{
public:
	friend ostream& operator << ( ostream&  strm, const Ant& );
	Ant(Color clr = Red) : m_color(clr),m_state(0), m_resting(0),m_direction(0),m_HasFood(false) {} // init
	int state() {return m_state;}
	Color color(){return m_color;}
	int  resting() {return m_resting;}
	int direction() { return m_direction;};
	bool has_food(){return m_HasFood;};
  void set_state(int s) {m_state = s;}
  void  set_resting(int r) { m_resting = r;}
  void  set_direction(int d) {m_direction = d;}
  void  set_has_food(bool hasFood) {m_HasFood = hasFood;}
  
public:
	Map::Position m_position;
	int m_id;
protected:
	Color m_color; 
	int m_state;
	int m_resting;
	int m_direction;
	bool m_HasFood;
};

ostream& operator << ( ostream&  strm, const Ant& ant )
{
	strm <<"id = "<< ant.m_id<<" state = "<<ant.m_state<<" direction = " << ant.m_direction << " rest = " <<ant.m_resting << " hasFood " << ant.m_HasFood;
	return strm;
}

class StateMachine
{
public:
	StateMachine(const std::vector<Instruction>& RedInstr,const std::vector<Instruction>& BlackInstr, Map& mp) 
		  : m_RedInstr(RedInstr)
			, m_BlackInstr(BlackInstr)
			, m_map(mp)
			, m_maxId(0)
	{
		InitAnts();
	}
protected:
	bool some_ant_is_at(const Map::Position& pos) const
	{
		//TODO improve
    for (std::vector<Ant>::const_iterator it = m_ants.begin();
			  it != m_ants.end();
			  ++it)
		{
			if (it->m_position == pos ) return true;
		}
		return false;
	}
	Ant& ant_at (const Map::Position& pos)
	{
		//TODO improve
	  for (std::vector<Ant>::iterator it = m_ants.begin();
			   it != m_ants.end();
			  ++it)
		{
		   if (pos == (*it).m_position) return *it;
		}
		assert(0);
	}
	void set_ant_at(const Map::Position& pos, Ant& ant)
	{
		ant.m_position = pos;
	}
	void clear_ant_at( ) {} // do nothing
	bool  ant_is_alive( int id ) 
	{
		 //return m_antsMap.find(id) != m_antsMap.end();
	  //TODO improve
	  for (std::vector<Ant>::iterator it = m_ants.begin();
			   it != m_ants.end();
			  ++it)
		{
			if ((*it).m_id == id) return true;
		}
		return false;
	}
	Map::Position find_ant(int id)
	{
		//TODO improve
		//return m_antsMap.find(id)->second->m_position;
	  for (std::vector<Ant>::iterator it = m_ants.begin();
			   it != m_ants.end();
			  ++it)
		{
			if ((*it).m_id == id) return (*it).m_position;
		}
		assert(0);
		return Map::Position(-1,-1);
	}
	void kill_ant_at(const Map::Position& pos)
	{
		//TODO improve remove_if
		for (std::vector<Ant>::iterator it = m_ants.begin(); it != m_ants.end(); ++it)
			if (it->m_position == pos) { /*m_antsMap.erase(it->m_id);*/m_ants.erase(it);  break;}
	}
	//cell
	bool cell_matches(const Map::Position& p, ECond cond, Color c, int i)
	{
			if ( m_map.rocky(p) ) return cond == Rock ? true : false;

     switch (cond)
		 {
			case Friend: return some_ant_is_at(p) && ant_at(p).color();
      case Foe: return some_ant_is_at(p) && ant_at(p).color() != c;
			case FriendWithFood: return some_ant_is_at(p) && ant_at(p).color() == c && ant_at(p).has_food();
			case FoeWithFood: return some_ant_is_at(p) && ant_at(p).color() != c && ant_at(p).has_food();
      case Food: return m_map.food_at(p) > 0;
      case Rock: return false;
      case Marker: m_map.check_marker_at(p, c, i);
			case FoeMarker: m_map.check_any_marker_at(p, Helper::other_color(c));
      case Home: return m_map.anthill_at(p, c);
      case FoeHome: return m_map.anthill_at(p, Helper::other_color(c));
			default : assert(0);
		 }
		 return false;
	}
	static unsigned int  fourth ( unsigned int seed)
	{
		for ( int i = 0; i < 4; i++)
		seed = seed * 22695477 + 1;
		return seed;
	}
public:
	
	void startLoop( int turns )
	{
		// TODO improve
		for (int i = 0; i < turns; i++ )
		{
      for(int j = 0; j < m_maxId; j++)
				step(j);
			std::cout<<"step  = " << i << endl;  
			dump();
		}
	}

protected:
	static int randomint(int n)
	{
		static unsigned int  seed = 12345;
		static unsigned int  si = fourth(seed);
		int x =  (si / 65536) % 16384;
		si = si * 22695477 + 1;
		return x % n;
	}
  
	void  step(int id) 
	{
     if (!ant_is_alive(id))  return;
		 Map::Position& p = find_ant(id);
     Ant&  ant = ant_at(p);
		 if (ant.resting() > 0 ) { ant.set_resting(ant.resting() - 1); return;}
		 
		 const std::vector<Instruction>& m_instr = ant.color() == Red ?  m_RedInstr : m_BlackInstr;
		 
		 const Instruction& inst = m_instr[ant.state()]; 
		 switch(inst.m_inst)
		 {
		   case EI_Sense: 
			 { 
				 Map::Position& pos = m_map.sensed_cell(p,ant.direction(),inst.m_dir);
				 int st = cell_matches(pos,inst.m_cond,ant.color(),inst.m_i) ? inst.m_st1 : inst.m_st2;
				 ant.set_state(st);
			 } break;
			 case EI_Mark: m_map.set_marker_at(p,ant.color(),inst.m_i); ant.set_state(inst.m_st1);break;
			 case EI_Unmark: m_map.clear_marker_at(p,ant.color(),inst.m_i); ant.set_state(inst.m_st1);break;
			 case EI_PickUp:  
			 { 
					 if ( ant.has_food() || m_map.food_at(p) == 0 ) ant.set_state(inst.m_st2);
					 else
					 {
						 m_map.set_food_at(p,m_map.food_at(p) - 1);
						 ant.set_has_food(true);
						 ant.set_state(inst.m_st1);
					 }
				} break;
				case EI_Drop:  
				{ 
					 if ( ant.has_food() ) 
					 {
						 m_map.set_food_at(p,m_map.food_at(p) + 1);
						 ant.set_has_food(false);
					 }
					 ant.set_state(inst.m_st1);
				} break;
				case EI_Turn: ant.set_direction(Helper::turn(inst.m_lr,ant.direction())); ant.set_state(inst.m_st1);break;
				case EI_Move:  
				{
					Map::Position newp =  m_map.adjacent_cell(p,ant.direction());
					if (m_map.rocky(newp) || some_ant_is_at(newp))
						ant.set_state(inst.m_st2);
					else
					{
						clear_ant_at();
            set_ant_at(newp, ant);
            ant.set_state( inst.m_st1);
            ant.set_resting(14);
            check_for_surrounded_ants(newp);
					}
				}break;
				case EI_Flip: {int st =  randomint( inst.m_p ) == 0 ? inst.m_st1 : inst.m_st2; ant.set_state(st);}break;

		 };
	}
		 int adjacent_ants(const 	Map::Position& p, Color c)
		 {
        int n = 0;
				for (int d = 0; d <= 5; d++)
				{
					Map::Position cel = m_map.adjacent_cell(p, d);
					if (some_ant_is_at(cel) && ant_at(cel).color() == c) n++;
				}
				return n;
		 }

     void check_for_surrounded_ant_at(const 	Map::Position& p)
     {
			  if (some_ant_is_at(p))
				{
					Ant a = ant_at(p);
					if ( adjacent_ants(p, Helper::other_color(a.color())) >= 5 )
					{
						kill_ant_at(p);
						m_map.set_food_at(p, m_map.food_at(p) + 3 + a.has_food() ?  1 : 0);
					}
				}
		 }
     void check_for_surrounded_ants(const 	Map::Position& p)
		 {
			  check_for_surrounded_ant_at(p);
				for ( int  d = 0; d <= 5; d++)
				{
          check_for_surrounded_ant_at(m_map.adjacent_cell(p,d));
				}
		 }
		 void addAnt(Map::Position& pos,Color c)
		 {
			  Ant a(c);
				a.m_id = m_maxId++;
				a.m_position = pos;
				//reserve before
				m_ants.push_back(a);
				//m_antsMap[(*m_ants.rbegin()).m_id] = (Ant*) &m_ants[ m_maxId++];
				
		 }
		 void dump()
		 {
			 //Improve
			 bool bFound (false);
			 Color c = Red;
			 for (int i = 0; i < m_map.szY(); i++)
			 {
					for (int j = 0; j < m_map.szX(); j++)
				  {
						Map::Position pos(j,i);
						bFound = false;
						Ant* pAnt(0);
						for( vector<Ant>::iterator it = m_ants.begin();
							 it != m_ants.end();
							 ++it)
						{
							if (it->m_position == pos) {bFound = true; pAnt = (Ant*)&(*it) ; c = it->color();break;} 
						}
						std::cout<<" "<< m_map.valAt(i,j);
						if (bFound) 
						{
							std::cout << *pAnt;
						}
						std::cout<<endl;
						
						
					}
					std::cout<<endl;
			 }
			 std::cout<<endl;
		 }
		 void InitAnts()
		 {
			 for (int i = 0 ; i <  m_map.szY(); i++)
				 for (int j = 0; j < m_map.szX(); j++)
					{
						if (m_map.isRedHill(i,j)) addAnt(Map::Position(j,i),Red);
						else if (m_map.isBlackHill(i,j)) addAnt(Map::Position(j,i),Black);
					}
		 }
protected:
	int m_maxId;
  
	const std::vector<Instruction>& m_RedInstr;
	const std::vector<Instruction>& m_BlackInstr;

	Map& m_map;
	std::vector<Ant> m_ants;
	//std::map<int,Ant*> m_antsMap;
};

void FillBrains(const std::string& fname, list<Instruction>& eval)
{
	std::ifstream strm;
	strm.open(fname.c_str());
	std::string str;
	while (!strm.eof())
	{
		char ch;
		strm.get(ch);
		str.push_back(ch);
	}
	strm.close();
	AntReader  rdr(eval);
	parse_info<> info = parse(str.c_str(), rdr, space_p| ch_p('\n') | ch_p(10) );	
}

int main(int argc, char** argv)
{

	if (argc != 4)
	{
		std::cout<<"Usage: Ants <map file> <red brains without comments> <black brains without comments>" << endl;
		exit(0);
	}
    
	Map m(argv[1]);

  list<Instruction> lstRed;
  FillBrains(argv[2],lstRed);
	std::vector<Instruction> vecRed(lstRed.begin(), lstRed.end());

	list<Instruction> lstBlack;
  FillBrains(argv[3],lstBlack);
	std::vector<Instruction> vecBlack(lstBlack.begin(), lstBlack.end());


	StateMachine st(vecRed,vecBlack, m);
	st.startLoop(100000);
  return 0;
}


